package com.sps.business.service.impl;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.sps.business.domain.*;
import com.sps.business.mapper.CcStockinfoInfoMapper;
import com.sps.business.mapper.CcWarehouserecordMapper;
import com.sps.business.mapper.JcItemInfoMapper;
import com.sps.common.constant.ApiUrl;
import com.sps.common.exception.ServiceException;
import com.sps.common.utils.DateUtils;
import com.sps.common.utils.SecurityUtils;
import com.sps.common.utils.StringUtils;
import com.sps.common.utils.http.HttpUtils;
import com.sps.common.utils.ip.IpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sps.business.mapper.CcOrderInfoMapper;
import com.sps.business.service.ICcOrderInfoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 订单信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-12-11
 */
@Service
public class CcOrderInfoServiceImpl implements ICcOrderInfoService 
{
    @Autowired
    private CcOrderInfoMapper ccOrderInfoMapper;

    @Autowired
    private JcItemInfoMapper jcItemInfoMapper;

    @Autowired
    private CcStockinfoInfoMapper ccStockinfoInfoMapper;

    @Autowired
    private CcWarehouserecordMapper ccWarehouserecordMapper;

    /**
     * 查询订单信息
     * 
     * @param id 订单信息主键
     * @return 订单信息
     */
    @Override
    public CcOrderInfo selectCcOrderInfoById(Long id)
    {
        return ccOrderInfoMapper.selectCcOrderInfoById(id);
    }

    /**
     * 查询订单信息列表
     * 
     * @param ccOrderInfo 订单信息
     * @return 订单信息
     */
    @Override
    public List<CcOrderInfo> selectCcOrderInfoList(CcOrderInfo ccOrderInfo)
    {
        return ccOrderInfoMapper.selectCcOrderInfoList(ccOrderInfo);
    }

    /**
     * 新增订单信息
     * 
     * @param ccOrderInfo 订单信息
     * @return 结果
     */
    @Override
    public int insertCcOrderInfo(CcOrderInfo ccOrderInfo)
    {
        return ccOrderInfoMapper.insertCcOrderInfo(ccOrderInfo);
    }

    /**
     * 修改订单信息
     * 
     * @param ccOrderInfo 订单信息
     * @return 结果
     */
    @Override
    public int updateCcOrderInfo(CcOrderInfo ccOrderInfo)
    {
        return ccOrderInfoMapper.updateCcOrderInfo(ccOrderInfo);
    }

    /**
     * 批量删除订单信息
     * 
     * @param ids 需要删除的订单信息主键
     * @return 结果
     */
    @Override
    public int deleteCcOrderInfoByIds(Long[] ids)
    {
        return ccOrderInfoMapper.deleteCcOrderInfoByIds(ids);
    }

    /**
     * 删除订单信息信息
     * 
     * @param id 订单信息主键
     * @return 结果
     */
    @Override
    public int deleteCcOrderInfoById(Long id)
    {
        return ccOrderInfoMapper.deleteCcOrderInfoById(id);
    }

    @Transactional
    @Override
    public String importOrder(List<CcOrderInfoExcel> orderList, String pcDate, String operName) {
        String message = "";
        if (StringUtils.isNull(orderList) || orderList.size() == 0)
        {
            throw new ServiceException("导入订单数据不能为空！");
        }

        //校验订单号是否已经存在了，先根据订单号去重
        // 使用Collectors.toMap去重，key为订单号
        List<CcOrderInfoExcel> uniorderList= orderList.stream()
                .collect(Collectors.toMap(
                        CcOrderInfoExcel::getOrderCode,  // key是订单号
                        ccOrderInfoExcel -> ccOrderInfoExcel, // value是ccOrderInfoExcel对象
                        (existing, replacement) -> existing // 如果有重复，保留第一个
                ))
                .values()
                .stream()
                .collect(Collectors.toList());
        for (CcOrderInfoExcel ccOrderInfoExcel : uniorderList) {
            //校验订单号
            Long count =  ccOrderInfoMapper.selectCcOrderInfoCountByOrderCode(ccOrderInfoExcel.getOrderCode());
            if(count>0){
                throw new ServiceException("订单号:"+ccOrderInfoExcel.getOrderCode()+"已存在");
            }
        }

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        int i = 0;
     //   List<CcOrderInfo> orderInfoList = new ArrayList<>();
        for (CcOrderInfoExcel ccOrderInfoExcel : orderList) {

            //校验不存在的物料
            JcItemInfo jcItemInfo = jcItemInfoMapper.selectJcItemInfoByItemCode(ccOrderInfoExcel.getItemCode());
            if(jcItemInfo==null){
                throw new ServiceException("物料号:"+ccOrderInfoExcel.getItemCode()+"不存在，请先维护基础信息!");
            }
            CcOrderInfo orderInfo = new CcOrderInfo();
            orderInfo.setOrderCode(ccOrderInfoExcel.getOrderCode());
            orderInfo.setItemCode(ccOrderInfoExcel.getItemCode());
            orderInfo.setDcNum(ccOrderInfoExcel.getDcNum());
            orderInfo.setItemName(jcItemInfo.getItemName());
            orderInfo.setLableCode(jcItemInfo.getLableCode());
            orderInfo.setApplianceyCode(jcItemInfo.getApplianceyCode());
            orderInfo.setApplianceyName(jcItemInfo.getApplianceyName());
            orderInfo.setSuppCode(jcItemInfo.getSuppCode());
            orderInfo.setSuppName(jcItemInfo.getSuppName());
            orderInfo.setFjNum(ccOrderInfoExcel.getFjNum());
            orderInfo.setUnit(jcItemInfo.getUnit());
            orderInfo.setSpsArea(jcItemInfo.getSpsArea());
            orderInfo.setLineCode(jcItemInfo.getLineCode());
            orderInfo.setLineName(jcItemInfo.getLineName());
            orderInfo.setPcDate(DateUtils.parseDate(pcDate));
            orderInfo.setRes2("未打印");
            orderInfo.setRes5("未扫描");
            //打印次数
            orderInfo.setSn(0L);
            orderInfo.setCreateTime(DateUtils.getNowDate());
            orderInfo.setCreateUser(SecurityUtils.getLoginUser().getUser().getNickName());
            //器具编号
            orderInfo.setRes3(jcItemInfo.getRes1());
            //段位
            orderInfo.setRes4(jcItemInfo.getRes2());
            //序列号（刚开始默认为0）
            orderInfo.setXlh(0L);
         //   orderInfoList.add(orderInfo);
            orderInfo.setOrderTs(ccOrderInfoExcel.getOrderTs());
            i = ccOrderInfoMapper.insertCcOrderInfo(orderInfo);
            successNum++;
        }


        if(i>0){
            message = "成功导入"+successNum+"条数据";
        }else{
            message="数据导入失败";
        }
        return message;
    }

    @Override
    public List<CcOrderInfo> selectCcOrderInfoListGroup(CcOrderInfo ccOrderInfo) {
        return ccOrderInfoMapper.selectCcOrderInfoListGroup(ccOrderInfo);
    }
    @Override
    public List<CcOrderInfo> selectCcOrderInfoListGroupFj(CcOrderInfo ccOrderInfo) {
        return ccOrderInfoMapper.selectCcOrderInfoListGroupFj(ccOrderInfo);
    }

    /**
     * 更新打印状态
     * @param ccOrderInfo
     * @return
     */
    @Override
    public int editOrderDyStatus(CcOrderInfo ccOrderInfo) {

        ccOrderInfo.setSn(ccOrderInfo.getSn()+1);
        ccOrderInfo.setRes2("已打印");
        return ccOrderInfoMapper.updateCcOrderDyInfoStatus(ccOrderInfo);
    }


    @Transactional
    @Override
    public int fjrwCcOrderInfoByorderCode(String orderCode) {

        //查询出订单下所有的数据
        List<CcOrderInfo> ccOrderInfoList = ccOrderInfoMapper.selectCcOrderInfoByOrderCode(orderCode);

        //处理分拣数量 2024-03-03
        for (CcOrderInfo ccOrderInfo : ccOrderInfoList) {
            //分拣数量 = 订单数量/订单台数，如果出现小数那么说明数据有误
            Long dcNum = ccOrderInfo.getDcNum();//订单用量
            Long orderTs = ccOrderInfo.getOrderTs();//订单台数
            long dcNumLong = dcNum;
            long orderTsLong = orderTs;
            // 处理可能的null值
            if (dcNum == null || orderTs == null) {
                throw new IllegalArgumentException("订单用量或订单台数不能为空值");
            }
            // 检查除数是否为0
            if (orderTsLong == 0) {
                throw new ArithmeticException("订单台数不能为0");
            }
            // 检查是否能整除
            if (dcNumLong % orderTsLong != 0) {
                throw new ArithmeticException("分拣必须是整数，物料号"+ccOrderInfo.getItemCode()+"当前结果为小数");
            }
            long fjNum = dcNumLong / orderTsLong;
            ccOrderInfo.setFjNum(fjNum);
        }


        //按照sps去分组
        Map<String, List<CcOrderInfo>> groupBySpsArea = ccOrderInfoList.stream().collect(Collectors.groupingBy(CcOrderInfo::getSpsArea));
            //遍历分组
             int i = 0;
             for (Map.Entry<String, List<CcOrderInfo>> entryOrder : groupBySpsArea.entrySet()) {
                 i++;
                 String spsArea = entryOrder.getKey();
                 List<CcOrderInfo> entryOrderList = entryOrder.getValue();
                 //查询当天最大分拣单
                 String resultStr = "";
                 Long maxXlh = ccOrderInfoMapper.selectCcOrderInfoByMaxXlh(DateUtils.dateTime(entryOrderList.get(0).getPcDate()));
                 Long resultNum = maxXlh+1;
                 String sequence = StringUtils.getDailySequence(entryOrderList.get(0).getPcDate(), resultNum);
                //更新分拣单号,res1(分拣单号)，用订单号orderCode,SPS区作为更新条件
                 i =  ccOrderInfoMapper.updateCcOrderInfoFjCode(sequence,"1",resultNum.toString(),DateUtils.getTime(), SecurityUtils.getLoginUser().getUser().getNickName(), orderCode,spsArea);

                 System.out.println("resultNum = " + resultNum);
             }
        return i;
    }

    /*
     * 分拣亮灯逻辑
     */
    @Transactional
    @Override
    public int removeLd(String res1) throws Exception {

        //得到分拣单下所有的数据
        CcOrderInfo searchOrder = new CcOrderInfo();
        searchOrder.setRes1(res1);
        searchOrder.setRes5("未扫描");
        List<CcOrderInfo> ccOrderInfoList = ccOrderInfoMapper.selectCcOrderInfoList(searchOrder);
        if(ccOrderInfoList==null||ccOrderInfoList.size()==0){
            throw new ServiceException("分拣单没有找到对应数据！");
        }

        //判断一下有没有未完成分拣单(已扫描但是没有分拣的单子)
        Long count =   ccOrderInfoMapper.selectCcOrderInfoCountByFj("已扫描");
        if(count>0){
            throw new ServiceException("已经有扫描的单据了,请先完成");
        }

        JSONArray LightList = new JSONArray();
        JSONObject result = new JSONObject();
        for (CcOrderInfo orderInfo : ccOrderInfoList) {
            String lableCode = orderInfo.getLableCode();
            JSONObject parObject = new JSONObject();
            parObject.put("locationId",lableCode);
            parObject.put("lightColor","22");
            parObject.put("twinkle",3);
            parObject.put("greenNum",orderInfo.getFjNum());
            parObject.put("redNum",Integer.valueOf(orderInfo.getApplianceyCode()));
            LightList.add(parObject);
        }
        result.put("LightList", LightList);
        String resultString = result.toString();
        System.out.println("resultString = " + resultString);
        String s = HttpUtils.sendPostJson(ApiUrl.BATCHURL,result.toString());
        JSONObject jsonObject = JSON.parseObject(s);

        String result1 = jsonObject.get("result").toString();

        System.out.println("jsonObject = " + jsonObject);

        if(result1.equals("0")){
            throw new ServiceException(jsonObject.get("message").toString());
        }
        //亮灯成功更改状态，更新分拣状态为已经扫描
        int i = ccOrderInfoMapper.updateCcOrderInfoFjCodeRes5("已扫描", res1);
        //降分拣单上的数据锁帐
        if(i>0){
            for (CcOrderInfo ccOrderInfo : ccOrderInfoList) {
                //1.查询库存,校验库存够不够
                CcStockinfoInfo ccStockinfoInfo = ccStockinfoInfoMapper.selectCcStockinfoInfoByItemId(ccOrderInfo.getItemCode());
                if(ccStockinfoInfo==null){
                    throw new ServiceException("物料号:"+ccOrderInfo.getItemCode()+"没有库存");
                }
                //可用数量
                long userNum = ccStockinfoInfo.getKcNum() - ccStockinfoInfo.getLockNum();
                //分拣数量
                Long fjNum = ccOrderInfo.getFjNum();
                if(fjNum>userNum){
                    throw new ServiceException("物料:"+ccStockinfoInfo.getItemId()+"库存不足");
                }
                //2.进行锁帐
                ccStockinfoInfo.setLockNum(fjNum);
                ccStockinfoInfoMapper.updateCcStockinfoInfo(ccStockinfoInfo);

            }
        }

        return i;
    }

    /*
     * 回传接口
     */
    @Transactional
    @Override
    public int passback(WebTest webTest) {
        int i = 0;
        //通过标签号回写分拣单信息
        String sid = webTest.getSid();
        //通过标签和和状态查询分拣单数据，一个分拣单中的标签号不能重复
        CcOrderInfo ccOrderInfo =  ccOrderInfoMapper.selectCcOrderInfoByLabCode(sid,"已扫描");
        if(ccOrderInfo==null){
            throw new ServiceException("货位:"+sid+"没有查询到数据");
        }
        ccOrderInfo.setRes5("分拣完成");
        i= ccOrderInfoMapper.updateCcOrderInfo(ccOrderInfo);
        //出库减账
        int update = ccStockinfoInfoMapper.updateCcStockinfoInfoByItemCode(ccOrderInfo.getFjNum().toString(), ccOrderInfo.getFjNum().toString(), ccOrderInfo.getItemCode());

        //记录出库流水
        //2.向流水表中增加数据
        CcWarehouserecord ccWarehouserecord = new CcWarehouserecord();
        ccWarehouserecord.setItemName(ccOrderInfo.getItemName());
        ccWarehouserecord.setItemId(ccOrderInfo.getItemCode());
        ccWarehouserecord.setBsinssType(1L);
        ccWarehouserecord.setCrNum(ccOrderInfo.getFjNum());
        ccWarehouserecord.setSupplyCode(ccOrderInfo.getSuppCode());
        ccWarehouserecord.setSupplyName(ccOrderInfo.getSuppName());
        ccWarehouserecord.setUnit(ccOrderInfo.getUnit());
        ccWarehouserecord.setKwCode("sps-001");
        ccWarehouserecord.setKwName("sps皮卡");
        ccWarehouserecord.setLableCode(ccOrderInfo.getLableCode());
        ccWarehouserecord.setApplianceyCode(ccOrderInfo.getApplianceyCode());
        ccWarehouserecord.setApplianceyName(ccOrderInfo.getApplianceyName());
        ccWarehouserecord.setSpsArea(ccOrderInfo.getSpsArea());
        ccWarehouserecord.setCreateBy(ccOrderInfo.getCreateBy());//创建人
        ccWarehouserecord.setCreateTime(DateUtils.getNowDate());//创建时间
        ccWarehouserecord.setUpdateBy(ccOrderInfo.getCreateBy());//更新人
        ccWarehouserecord.setUpdateTime(DateUtils.getNowDate());//更新时间
        ccWarehouserecordMapper.insertCcWarehouserecord(ccWarehouserecord);
        return i;
    }

    @Override
    public int deleteCcOrderInfoByOrderCode(String orderCode) {
        return ccOrderInfoMapper.deleteCcOrderInfoByOrderCode(orderCode);
    }


}
